//
//  JCokeRPCService.swift
//  Center_RPC
//
//  Created by Flutter on 2021/7/12.
//

import Foundation
import GRPC
import RPC
import Storage

public final class JCokeRPCService: RPCService {
    private let name: String = "JCoke"
    private let store: Store
    let resultQueue = DispatchQueue.main
    let requestQueue = DispatchQueue(label: typeName)
    let context: JCokeRPCServiceContextual

    public init(store: Store, context: JCokeRPCServiceContextual) {
        self.store = store
        self.context = context
        let remote = (try? store.sync.get(key: Self.remoteKey)) ?? Self.remote
        super.init(name: name, host: remote.host, port: remote.port, cert: remote.cert, trustHost: remote.trustHost)
    }
}

public extension JCokeRPCService {
    func callOptions(additionHeader: [(String, String)] = []) -> CallOptions {
        let sessionID = context.sessionID
        let bundleID = Bundle.main.bundleIdentifier ?? ""
        let version = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? ""

        let defaultHeaders = [
            ("X-JCOKE-SID", sessionID),
            ("X-JCOKE-BID", bundleID),
            ("X-JCOKE-VERSION", version),
        ]

        let allHeaders = defaultHeaders + additionHeader
        
        return CallOptions(
            customMetadata: .init(allHeaders),
            timeLimit: .timeout(.seconds(10)),
            cacheable: true,
            logger: logger
        )
    }
}

public extension JCokeRPCService {
    func update(host: String, port: Int, cert: String?, trustHost: String?) {
        let rCert = cert ?? JCokeRPCService.cert
        let rTrustHost = trustHost ?? JCokeRPCService.trustHost
        change(host: host, port: port, cert: rCert, trustHost: rTrustHost)
        let remote = Remote(host: host, port: port, cert: rCert, trustHost: rTrustHost)
        store.async.put(value: remote, forKey: Self.remoteKey, complete: { _ in })
    }
}

private extension JCokeRPCService {
    
    static let name: String = "JCoke"
    #if DEBUG
        static let host: String = "djangoc.com"
    #else
        static let host: String = "djangoc.com"
    #endif
    
    static let port: Int = 4443
    
    static let cert: String = """
-----BEGIN CERTIFICATE-----
MIIDBjCCAe4CCQDA5wiUDbvlvzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJD
TjERMA8GA1UEBwwIU2hhbmdoYWkxDTALBgNVBAoMBGdlYWsxFDASBgNVBAMMC2Rq
YW5nb2MuY29tMB4XDTIxMDUyNjAxNDQyMloXDTMxMDUyNDAxNDQyMlowRTELMAkG
A1UEBhMCQ04xETAPBgNVBAcMCFNoYW5naGFpMQ0wCwYDVQQKDARnZWFrMRQwEgYD
VQQDDAtkamFuZ29jLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AL5wLEcdYjhOgUUG0nZzQ7p0VG3wL9/RNc27DdIc+b3Z1L/P/WJw3KDtEvKTImQE
Rtw9aFCXlfNeSIhrQSbqHYXJ/g5daLY/rZjB/Hh4wUqN7rCt4n5cFPnFY24XY1ON
s+cjl3ulZdE5GoXZA+bGJskqnE/6lQEfes+IA3zFaGvsaNJrY01pVk9e5vqiBeSb
ZEeM+PkSyjFmgf5jgKL/yqTxM13b0UhIG2ZWt7xnINpeaXXLGDq2bJTRog5Lof5V
Merm7ye9UI7R3z66FQlz1a+dS3XNxGpl2skQ12vm3CU94olSdqLvMUQVa9rdhwch
CvxE/rEkSm8NEJ+4yCe3svkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAkcD21NIe
RUYsxzp7B2950XOEH004C6NnoT20CHOEpgYN0b6nJzv+h32q3jFLPjLTUfBEOzXt
HN8NrGtXSxnxWbdTSKXkcjQCsQwXCHEL/MtNYVKAJkdpX3qxB3ITO4DZnl0X82GA
3hc834SWSIXUzRGhk1ncrZKjgUb6udjo/BdwKBTLkTT1Cv0fgCpl8EvGYMoZHmly
K2+vDVQGsgV5Ek6aZ1GgdE/lPsAqcRLw6EwgnhFsvroIRI6T4jKPcugswFCcb8wx
MPqEO25rbiaYhLEAY6oCzkZy6PKOX1Pk2N2gpU0X/4KUCHWGmMFApUkQDnAPJi4O
j/V/7ioSK5eQ2Q==
-----END CERTIFICATE-----
"""
    static let trustHost: String = "djangoc.com"
    
    static let remote = Remote(host: host, port: port, cert: cert, trustHost: trustHost)

    static let remoteKey: String = "\(typeName)/\(name)/remote"
}
